﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using EPiBoost.Core.Model.TemplateParameters;
using EPiServer.Editor;
using EPiServer.Web;

namespace EPiBoost.Core.Web.Mvc.Html
{
	public static class Helpers
	{
		public static bool EditMode(HtmlHelper html)
		{
			return EditMode(html.ViewContext.RequestContext.RouteData);
		}

		public static bool EditMode(System.Web.Routing.RouteData routeData)
		{
			return (bool)(routeData.GetContextMode() == ContextMode.Edit);
		}


		public static ContextMode GetContextMode(this System.Web.Routing.RouteData routeData)
		{
			object obj2;
			if (routeData.DataTokens.TryGetValue("contextmode", out obj2))
			{
				return (ContextMode)obj2;
			}
			if (!PageEditing.PageIsInEditMode)
			{
				return ContextMode.Default;
			}
			return ContextMode.Edit;
		}

		public static WrapperSettings LoadWrapperSetttings(HtmlHelper html)
		{
			var result = new WrapperSettings();
			var settings = html.ViewContext.ViewData["wrapperSettings"];
			if (settings != null)
			{
				if (settings is WrapperSettings)
				{
					result = settings as WrapperSettings;
				}
				else if(settings is Newtonsoft.Json.Linq.JObject)
				{
					result = (settings as Newtonsoft.Json.Linq.JObject).ToObject<WrapperSettings>();
				}
			} 
			return result;
		}

		public static RowSettings LoadRowSetttings(HtmlHelper html)
		{
			var result = new RowSettings();
			var settings = html.ViewContext.ViewData["rowSettings"];
			if (settings != null)
			{
				if (settings is RowSettings)
				{
					result = settings as RowSettings;
				}
				else if (settings is Newtonsoft.Json.Linq.JObject)
				{
					result = (settings as Newtonsoft.Json.Linq.JObject).ToObject<RowSettings>();
				}
			} 
			return result;
		}


		public static bool OpenWrapper(HtmlHelper html, WrapperSettings settings, int? index = null, int total = 0,
		                               RowSettings rowSettings = null)
		{
			if (EditMode(html) && !settings.EnableInEditMode)
			{
				return false;
			}

			int i = index != null ? index.Value : -2;

			if (settings.Class != null)
			{
				var classNames = GetWrapperClassNames(settings, total, rowSettings, i);

				html.ViewContext.Writer.Write("<{0} class=\"{1}\">", settings.Element, classNames);
				return true;
			}
			return false;
		}

		public static string GetWrapperClassNames(WrapperSettings settings, int total, RowSettings rowSettings, int i)
		{
			string classNames = settings.Class;
			if (i > 0 && i%2 == 1 && !string.IsNullOrEmpty(settings.AlternatingClass))
			{
				classNames += string.Format(" {0}", settings.AlternatingClass);
			}
			if (i == 0 && !string.IsNullOrEmpty(settings.FirstClass))
			{
				classNames += string.Format(" {0}", settings.FirstClass);
			}
			if (i == total - 1 && !string.IsNullOrEmpty(settings.LastClass))
			{
				classNames += string.Format(" {0}", settings.LastClass);
			}
			if (i >= 0 && !string.IsNullOrEmpty(settings.IndexFormat))
			{
				classNames += string.Format(" {0}", string.Format(settings.IndexFormat, i));
			}

			if (i > 0 && rowSettings != null && rowSettings.ItemsPerRow > 0)
			{
				int positionInrow = i%rowSettings.ItemsPerRow;

				if (positionInrow%2 == 1 && !string.IsNullOrEmpty(rowSettings.WrapperAlternatingClass))
				{
					classNames += string.Format(" {0}", rowSettings.WrapperAlternatingClass);
				}
				if (positionInrow == 0 && !string.IsNullOrEmpty(rowSettings.WrapperFirstClass))
				{
					classNames += string.Format(" {0}", rowSettings.WrapperFirstClass);
				}
				if ((positionInrow == rowSettings.ItemsPerRow - 1 || i == total - 1) &&
				    !string.IsNullOrEmpty(rowSettings.WrapperLastClass))
				{
					classNames += string.Format(" {0}", rowSettings.WrapperLastClass);
				}
				if (!string.IsNullOrEmpty(rowSettings.WrapperIndexFormat))
				{
					classNames += string.Format(" {0}", string.Format(rowSettings.WrapperIndexFormat, positionInrow));
				}
			}
			return classNames;
		}

		public static void CloseWrapper(HtmlHelper html, WrapperSettings settings)
		{
			if (EditMode(html) && !settings.EnableInEditMode) { return; }

			html.ViewContext.Writer.Write("</{0}>", settings.Element);
		}

		public static void TryOpenRow(HtmlHelper html, RowSettings settings, int index, int total)
		{
			if (EditMode(html) && !settings.EnableInEditMode) { return; }
			if (settings.DisableWrapperElement) { return; }
			
			if (!string.IsNullOrEmpty(settings.Element) && settings.ItemsPerRow > 0)
			{
				if (index % settings.ItemsPerRow == 0) // start of a new row
				{
					int rowIndex = index/settings.ItemsPerRow;
					int totalRows = (int) Math.Ceiling(((double) total)/settings.ItemsPerRow);

					string classNames = settings.Class;

					if (rowIndex > 0 && rowIndex % 2 == 1 && !string.IsNullOrEmpty(settings.AlternatingClass))
					{
						classNames += string.Format(" {0}", settings.AlternatingClass);
					}
					if (rowIndex == 0 && !string.IsNullOrEmpty(settings.FirstClass))
					{
						classNames += string.Format(" {0}", settings.FirstClass);
					}
					if (rowIndex == totalRows - 1 && !string.IsNullOrEmpty(settings.LastClass))
					{
						classNames += string.Format(" {0}", settings.LastClass);
					}
					if (!string.IsNullOrEmpty(settings.IndexFormat))
					{
						classNames += string.Format(" {0}", string.Format(settings.IndexFormat, rowIndex));
					}

					html.ViewContext.Writer.Write("<{0} class=\"{1}\">", settings.Element, classNames);
				}
			}
		}

		public static void TryCloseRow(HtmlHelper html, RowSettings settings, int index, int total)
		{
			if (EditMode(html) && !settings.EnableInEditMode) { return; }
			if (settings.DisableWrapperElement) { return; }

			if (settings.Class != null && settings.ItemsPerRow > 0)
			{
				if (index == total - 1 || index%settings.ItemsPerRow == settings.ItemsPerRow - 1)
				{
					html.ViewContext.Writer.Write("</{0}>", settings.Element);
				}
			}
		}
	}
}
